local skynet = require "skynet"


local CMD = {}
local SOCKET = {}
local gate
local agent = {}

local aplayid = {}

local astore = {}
local alast  = 1

local function apush(a)
	astore[alast] = a
	alast = alast + 1
end

local function apop()
	if alast > 1 then
		alast = alast - 1
	end
	local v = astore[alast]
	astore[alast] = nil
	return v
end

function SOCKET.open(fd, addr)
	skynet.error("New client from : " .. addr)
	agent[fd] = skynet.newservice("agent")
	--agent[fd] = apop()

	if agent[fd] == nil then
		skynet.error("apop get a nil agent")
		return
	end
	skynet.call(agent[fd], "lua", "start", { gate = gate, client = fd, watchdog = skynet.self(), clientaddr = addr })
end

local function close_agent(fd)
	local a = agent[fd]
	--apush(a)
	aplayid[fd] = nil
	agent[fd] = nil
	if a then
		skynet.call(gate, "lua", "kick", fd)
		skynet.send(a, "lua", "disconnect")
	end
end

function SOCKET.close(fd)
	skynet.error("socket close",fd)
	close_agent(fd)
end

function SOCKET.error(fd, msg)
	skynet.error("socket error",fd, msg)
	close_agent(fd)
end

function SOCKET.warning(fd, size)
	skynet.error("socket warning", fd, size)
end

function SOCKET.data(fd, msg)
end

function CMD.login(playid,fd)
	skynet.error("watchlog: login "..playid.." fd "..fd)
	aplayid[playid] = fd
end

function CMD.logout(playid)
	skynet.error("watchlog:  logout "..playid)
	aplayid[playid] = nil
end

function CMD.getPlay(playidT)
	
	local ret = {}

	for i=1, 16 do
		local id = playidT[i]
		if id ~= nil then
			--skynet.error("1 playerid = "..id)
			if aplayid[id] ~= nil then
				--skynet.error("2 player fd = "..aplayid[id])
				ret[i] = aplayid[id]     -- 取player id is fd
			end
		end
	end

	return ret
end

function CMD.start(conf)
	skynet.call(gate, "lua", "open" , conf)
	--[[
	for i=1, conf.maxclient do
		apush(skynet.newservice("agent"))
	end
	--]]
end

function CMD.close(fd)
	close_agent(fd)
end

skynet.start(function()
	skynet.dispatch("lua", function(session, source, cmd, subcmd, ...)
		if cmd == "socket" then
			local f = SOCKET[subcmd]
			f(...)
			-- socket api don't need return
		else
			local f = assert(CMD[cmd])
			skynet.ret(skynet.pack(f(subcmd, ...)))
		end
	end)

	gate = skynet.newservice("gate")
end)
